<template>
  <div class="audio-management">
    <el-card class="box-card">
      <template #header>
        <div class="card-header">
          <span>音频文件管理</span>
          <el-button type="primary" @click="handleUpload">上传音频</el-button>
        </div>
      </template>

      <!-- 搜索和筛选 -->
      <div class="filter-container">
        <el-input
          v-model="searchQuery"
          placeholder="搜索文件名"
          class="filter-item"
          @input="handleSearch"
        />
        <el-select v-model="sortBy" placeholder="排序方式" class="filter-item" @change="handleSort">
          <el-option label="上传时间" value="createdAt" />
          <el-option label="文件大小" value="size" />
          <el-option label="文件名" value="fileName" />
        </el-select>
      </div>

      <!-- 文件列表 -->
      <el-table
        v-loading="loading"
        :data="filteredFiles"
        style="width: 100%"
        border
      >
        <el-table-column prop="fileName" label="文件名" min-width="200">
          <template #default="{ row }">
            <div class="file-name">
              <el-icon><Document /></el-icon>
              <span>{{ row.originalName }}</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="size" label="大小" width="120">
          <template #default="{ row }">
            {{ formatFileSize(row.size) }}
          </template>
        </el-table-column>
        <el-table-column prop="createdAt" label="上传时间" width="180">
          <template #default="{ row }">
            {{ formatDate(row.createdAt) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200" fixed="right">
          <template #default="{ row }">
            <el-button-group>
              <el-button type="primary" @click="handlePreview(row)">
                预览
              </el-button>
              <el-button type="danger" @click="handleDelete(row)">
                删除
              </el-button>
            </el-button-group>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :total="total"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>

    <!-- 上传对话框 -->
    <el-dialog
      v-model="uploadDialogVisible"
      title="上传音频文件"
      width="500px"
    >
      <el-upload
        class="upload-demo"
        drag
        action="/api/audio/upload"
        :headers="uploadHeaders"
        :on-success="handleUploadSuccess"
        :on-error="handleUploadError"
        :before-upload="beforeUpload"
        accept="audio/*"
      >
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">
          将文件拖到此处，或<em>点击上传</em>
        </div>
        <template #tip>
          <div class="el-upload__tip">
            只能上传音频文件，且不超过10MB
          </div>
        </template>
      </el-upload>
    </el-dialog>

    <!-- 预览对话框 -->
    <el-dialog
      v-model="previewDialogVisible"
      title="音频预览"
      width="400px"
    >
      <div class="audio-preview">
        <audio
          v-if="currentFile"
          :src="currentFile.filePath"
          controls
          class="audio-player"
        />
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Document, UploadFilled } from '@element-plus/icons-vue'
import type { UploadProps } from 'element-plus'
import { useUserStore } from '@/stores/user'

interface AudioFile {
  fileName: string
  originalName: string
  filePath: string
  size: number
  createdAt: string
}

const userStore = useUserStore()
const loading = ref(false)
const files = ref<AudioFile[]>([])
const searchQuery = ref('')
const sortBy = ref('createdAt')
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
const uploadDialogVisible = ref(false)
const previewDialogVisible = ref(false)
const currentFile = ref<AudioFile | null>(null)

// 上传相关
const uploadHeaders = computed(() => ({
  Authorization: `Bearer ${userStore.token}`
}))

// 获取文件列表
const fetchFiles = async () => {
  try {
    loading.value = true
    const response = await fetch('/api/audio', {
      headers: {
        Authorization: `Bearer ${userStore.token}`
      }
    })
    const data = await response.json()
    files.value = data
    total.value = data.length
  } catch (error) {
    ElMessage.error('获取文件列表失败')
  } finally {
    loading.value = false
  }
}

// 过滤和排序后的文件列表
const filteredFiles = computed(() => {
  let result = [...files.value]
  
  // 搜索过滤
  if (searchQuery.value) {
    result = result.filter(file => 
      file.originalName.toLowerCase().includes(searchQuery.value.toLowerCase())
    )
  }
  
  // 排序
  result.sort((a, b) => {
    if (sortBy.value === 'createdAt') {
      return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
    } else if (sortBy.value === 'size') {
      return b.size - a.size
    } else {
      return a.originalName.localeCompare(b.originalName)
    }
  })
  
  // 分页
  const start = (currentPage.value - 1) * pageSize.value
  const end = start + pageSize.value
  return result.slice(start, end)
})

// 文件大小格式化
const formatFileSize = (size: number) => {
  if (size < 1024) {
    return size + ' B'
  } else if (size < 1024 * 1024) {
    return (size / 1024).toFixed(2) + ' KB'
  } else {
    return (size / (1024 * 1024)).toFixed(2) + ' MB'
  }
}

// 日期格式化
const formatDate = (date: string) => {
  return new Date(date).toLocaleString()
}

// 上传相关方法
const handleUpload = () => {
  uploadDialogVisible.value = true
}

const beforeUpload: UploadProps['beforeUpload'] = (file) => {
  const isAudio = file.type.startsWith('audio/')
  const isLt10M = file.size / 1024 / 1024 < 10

  if (!isAudio) {
    ElMessage.error('只能上传音频文件！')
    return false
  }
  if (!isLt10M) {
    ElMessage.error('文件大小不能超过 10MB！')
    return false
  }
  return true
}

const handleUploadSuccess: UploadProps['onSuccess'] = (response) => {
  ElMessage.success('上传成功')
  uploadDialogVisible.value = false
  fetchFiles()
}

const handleUploadError: UploadProps['onError'] = () => {
  ElMessage.error('上传失败')
}

// 预览相关方法
const handlePreview = (file: AudioFile) => {
  currentFile.value = file
  previewDialogVisible.value = true
}

// 删除相关方法
const handleDelete = async (file: AudioFile) => {
  try {
    await ElMessageBox.confirm(
      '确定要删除这个文件吗？',
      '警告',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    
    const response = await fetch(`/api/audio/${file.fileName}`, {
      method: 'DELETE',
      headers: {
        Authorization: `Bearer ${userStore.token}`
      }
    })
    
    if (response.ok) {
      ElMessage.success('删除成功')
      fetchFiles()
    } else {
      throw new Error('删除失败')
    }
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除失败')
    }
  }
}

// 分页相关方法
const handleSizeChange = (val: number) => {
  pageSize.value = val
  currentPage.value = 1
}

const handleCurrentChange = (val: number) => {
  currentPage.value = val
}

// 搜索和排序
const handleSearch = () => {
  currentPage.value = 1
}

const handleSort = () => {
  currentPage.value = 1
}

// 初始化
onMounted(() => {
  fetchFiles()
})
</script>

<style scoped>
.audio-management {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.filter-container {
  margin-bottom: 20px;
  display: flex;
  gap: 10px;
}

.filter-item {
  width: 200px;
}

.file-name {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.audio-preview {
  display: flex;
  justify-content: center;
  padding: 20px;
}

.audio-player {
  width: 100%;
}
</style> 